package com.cskaoyan.wordmemorize.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.listener.ReadListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cskaoyan.wordmemorize.auth.StpKit;
import com.cskaoyan.wordmemorize.common.constant.CommonConstant;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.common.exception.ExcelParseException;
import com.cskaoyan.wordmemorize.converter.VocConverter;
import com.cskaoyan.wordmemorize.dao.entity.*;
import com.cskaoyan.wordmemorize.dao.mapper.*;
import com.cskaoyan.wordmemorize.dto.admin.*;
import com.cskaoyan.wordmemorize.dto.app.DisplayBookVocDTO;
import com.cskaoyan.wordmemorize.dto.app.DisplayChapterDTO;
import com.cskaoyan.wordmemorize.dto.app.UserBookStatisticsDTO;
import com.cskaoyan.wordmemorize.request.*;
import com.cskaoyan.wordmemorize.service.FileService;
import com.cskaoyan.wordmemorize.service.VocService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Service
public class VocServiceImpl extends ServiceImpl<VocMapper, VocDO> implements VocService {
    @Resource
    VocMapper vocMapper;

    @Resource
    VocConverter vocConverter;

    @Resource
    VocMeaningMapper vocMeaningMapper;

    @Resource
    UserFavoriteMapper userFavoriteMapper;

    @Resource
    ExampleSentenceMapper exampleSentenceMapper;

    @Resource
    VocChapBookMapper vocChapBookMapper;


    @Resource
    VocBookMapper vocBookMapper;

    @Resource
    FileService fileService;

    @Resource
    VocChapterMapper vocChapterMapper;


    // 分页获取所有单词信息
    @Override
    public PageDTO<VocDTO> getVocabularies(VocPageRequest pageQuery) {

        Integer count1 = pageQuery.getCount();
        Integer pageNum = pageQuery.getPageNum();

        pageNum = count1 * (pageNum - 1);
        pageQuery.setPageNum(pageNum);

        List<VocDO> vocDOs = vocMapper.getVocDOs(pageQuery);

        Long count = vocMapper.getCount(pageQuery);


        return vocConverter.vocList2Page(vocDOs, count);
    }


    /**
     * 新增单词
     *
     * @param command
     */
    @Transactional
    @Override
    public void addVoc(VocCommand command) {
        VocDO vocDO = vocConverter.command2VocDO(command);

        vocMapper.insert(vocDO);
        Long id = vocDO.getId();
        //  插入voc_meaning 表
        List<VocMeaningCommand> interpretations = command.getInterpretations();

        List<VocMeaningDO> vocMeaningDOS = vocConverter.commands2VocMeaningDOs(interpretations);
        for (VocMeaningDO vocMeaningDO : vocMeaningDOS) {
            vocMeaningDO.setVocId(id);
            vocMeaningMapper.insert(vocMeaningDO);
        }

        // 插入example_sentence 表
        List<ExampleSentenceCommand> examples = command.getExamples();
        List<ExampleSentenceDO> exampleSentenceDOs = vocConverter.commands2ExampleSentenceDOs(examples);

        for (ExampleSentenceDO exampleSentenceDO : exampleSentenceDOs) {
            exampleSentenceDO.setVocId(id);
            exampleSentenceMapper.insert(exampleSentenceDO);
        }

        // 插入voc_chap_book 表
        // 同步去修改单词章节数量
        List<VocChapBookCommand> relations = command.getRelations();
        List<VocChapBookDO> vocChapBookDOs = vocConverter.commands2VocChapBookDOs(relations);

        for (VocChapBookDO vocChapBookDO : vocChapBookDOs) {
            vocChapBookDO.setVocId(id);
            vocChapBookMapper.insert(vocChapBookDO);
            UpdateWrapper<VocChapterDO> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", vocChapBookDO.getChapterId())
                    .setSql("voc_count = voc_count + 1");
            vocChapterMapper.update(updateWrapper);
        }


    }

    // 修改单词信息
    @Override
    @Transactional
    public void updateVoc(VocCommand command) {
        VocDO vocDO = vocConverter.command2VocDO(command);

        vocMapper.updateById(vocDO);

        //  修改voc_meaning 表
        List<VocMeaningCommand> interpretations = command.getInterpretations();
        List<VocMeaningDO> vocMeaningDOS = vocConverter.commands2VocMeaningDOs(interpretations);

        for (VocMeaningDO vocMeaningDO : vocMeaningDOS) {

            if (vocMeaningDO.getId() == null) {
                vocMeaningMapper.insert(vocMeaningDO);
            } else {
                // 包含key 则修改
                vocMeaningMapper.updateById(vocMeaningDO);
            }
        }


        // 修改example_sentence 表
        List<ExampleSentenceCommand> examples = command.getExamples();
        List<ExampleSentenceDO> exampleSentenceDOs = vocConverter.commands2ExampleSentenceDOs(examples);

        for (ExampleSentenceDO exampleSentenceDO : exampleSentenceDOs) {

            if (exampleSentenceDO.getId() == null) {
                exampleSentenceMapper.insert(exampleSentenceDO);
            } else {
                exampleSentenceMapper.updateById(exampleSentenceDO);
            }
        }


        // 插入voc_chap_book 表
        List<VocChapBookCommand> relations = command.getRelations();
        List<VocChapBookDO> vocChapBookDOs = vocConverter.commands2VocChapBookDOs(relations);

        for (VocChapBookDO vocChapBookDO : vocChapBookDOs) {

            if (vocChapBookDO.getId() == null) {
                //  新增voc_chap_book表中的数据时  需要去章节表中修改单词数量
                vocChapBookMapper.insert(vocChapBookDO);
                UpdateWrapper<VocChapterDO> VocChapterWrapper = new UpdateWrapper<VocChapterDO>().eq("id", vocChapBookDO.getChapterId()).setSql("voc_count = voc_count + 1");
                vocChapterMapper.update(VocChapterWrapper);
            } else {
                vocChapBookMapper.updateById(vocChapBookDO);
            }
        }


    }

    // 删除单词信息
    @Override
    @Transactional
    public DeleteVocOperateDTO deleteVocabulary(Long vocId) {
        // 1、删除voc表
        VocDO vocDO = vocMapper.selectById(vocId);
        vocMapper.deleteById(vocId);
        // 2 删除 voc_meaning 表  注意可能有多条数据
        vocMeaningMapper.delete(new QueryWrapper<VocMeaningDO>().eq("voc_id", vocId));
        // 3 删除 example_sentence 表  注意可能有多条数据
        exampleSentenceMapper.delete(new QueryWrapper<ExampleSentenceDO>().eq("voc_id", vocId));
        // 4 删除 voc_chap_book 表  注意可能有多条数据
        // 4.1 从voc_chap_book表中获取章节id
        List<VocChapBookDO> vocChapBookDOList = vocChapBookMapper.selectList(new QueryWrapper<VocChapBookDO>().eq("voc_id", vocId));


        vocChapBookMapper.delete(new QueryWrapper<VocChapBookDO>().eq("voc_id", vocId));


        // 4.2 修改voc_chapter表中的单词数量
        for (VocChapBookDO vocChapBookDO : vocChapBookDOList) {
            UpdateWrapper<VocChapterDO> updateWrapper = new UpdateWrapper<VocChapterDO>().eq("id", vocChapBookDO.getChapterId()).setSql("voc_count = voc_count - 1");
            vocChapterMapper.update(updateWrapper);
        }

        // 5 删除oss的文件
        if (vocDO.getUkPronounciation() != null) {
            fileService.deleteFile(vocDO.getUsPronounciation());
        }
        if (vocDO.getUsPronounciation() != null) {
            fileService.deleteFile(vocDO.getUsPronounciation());
        }


        // 6 构建返回对象并返回

        DeleteVocOperateDTO deleteVocOperateDTO = new DeleteVocOperateDTO();
        deleteVocOperateDTO.setId(vocId);
        deleteVocOperateDTO.setContent(vocDO.getContent());


        return deleteVocOperateDTO;
    }

    @Override
    @Transactional
    public List<DeleteVocOperateDTO> deleteVocabularies(BatchDeleteCommand command) {

        List<String> ids = command.getIds();

        ArrayList<DeleteVocOperateDTO> deleteVocOperateDTOS = new ArrayList<>();

        for (String id : ids) {


            VocDO vocDO = vocMapper.selectById(id);

            // 调用单词删除方法
            this.deleteVocabulary(Long.parseLong(id));

            DeleteVocOperateDTO deleteVocOperateDTO = new DeleteVocOperateDTO();
            deleteVocOperateDTO.setId(Long.parseLong(id));
            deleteVocOperateDTO.setContent(vocDO.getContent());
            deleteVocOperateDTOS.add(deleteVocOperateDTO);
        }


        return deleteVocOperateDTOS;
    }

    /**
     * @param vocId
     * @return
     */
    @Override
    public List<VocChapBookDTO> getVocRelations(Long vocId) {

        List<VocChapBookDO> vocRelations = vocChapBookMapper.selectList(
                new QueryWrapper<VocChapBookDO>()
                        .eq("voc_id", vocId)
        );


        for (VocChapBookDO vocRelation : vocRelations) {
            VocBookDO vocBookDO = vocBookMapper.selectById(vocRelation.getBookId());

            vocRelation.setCategoryName(vocBookDO.getName());
            vocRelation.setCategoryId(vocBookDO.getBcId());
        }


        return vocConverter.vocChapBookDOs2DTOs(vocRelations);
    }

    /**
     * app 获取无章节单词信息
     *
     * @param pageRequest
     * @return
     */
    @Override
    public PageDTO<DisplayBookVocDTO> getDisplayBookVocsInfo(AppVocPageRequest pageRequest) {


        int offset = (pageRequest.getPageNum() - 1) * pageRequest.getCount();

        List<VocDO> vocsOfUserBook = vocMapper.getVocsOfUserBook(StpKit.USER.getLoginIdAsLong(), Long.parseLong(pageRequest.getBookId()), offset, pageRequest.getCount());

        List<DisplayBookVocDTO> displayBookVocDTOS = vocConverter.vocDos2DisplayChapterVocDTOs(vocsOfUserBook);
        PageDTO<DisplayBookVocDTO> pageDTO = new PageDTO<>();
        pageDTO.setPageList(displayBookVocDTOS);
        return pageDTO;
    }

    /**
     * app  获取有章节单词数据
     *
     * @param pageRequest
     * @return
     */
    @Override
    public PageDTO<DisplayChapterDTO> getDisplayBookChapterVocsInfo(AppVocPageRequest pageRequest) {

        int offset = (pageRequest.getPageNum() - 1) * pageRequest.getCount();
        List<VocChapterDO> chapterVocsOfUserBook = vocMapper.getChapterVocsOfUserBook(StpKit.USER.getLoginIdAsLong(),
                Long.parseLong(pageRequest.getBookId()),
                offset,
                pageRequest.getCount());

        List<DisplayChapterDTO> displayChapterDTOS = vocConverter.vocChapterDOs2displayChapterDTOs(chapterVocsOfUserBook);


        PageDTO<DisplayChapterDTO> displayChapterDTOPageDTO = new PageDTO<>();
        displayChapterDTOPageDTO.setPageList(displayChapterDTOS);

        return displayChapterDTOPageDTO;

    }

    /**
     * app 获取单词详细信息
     *
     * @param vocId
     * @param userId
     * @return
     */
    @Override
    public VocDTO getVocDetail(Long vocId, Long userId) {


        VocDO vocDetail = vocMapper.getVocDetail(userId, vocId);
        if (vocDetail == null) {
            throw new BusinessException(ResultCodeEnum.FAIL);
        }


        LambdaQueryWrapper<UserFavoriteDO> favoriteWrapper = Wrappers.lambdaQuery(UserFavoriteDO.class)
                .eq(UserFavoriteDO::getUserId, userId)
                .eq(UserFavoriteDO::getVocId, vocId);
        // 获取用户是否收藏
        Long count = userFavoriteMapper.selectCount(favoriteWrapper);
        vocDetail.setFavorite(count > 0 ? 1 : 0);
        return vocConverter.vocDO2DTO(vocDetail);
    }

    // app 获取书籍中单词总数量 当前用户已选的数量 未选择数量
    @Override
    public UserBookStatisticsDTO getUserChooseCountInBook(Long userId, Long bookId) {

        // 该书籍的单词总数  注意一个单词可能属于多本书籍
        // voc_chap_book表中查询所有该书籍的单词总数
        Integer selectedCount = vocMapper.getAllVocsOfUserBook(userId, bookId);
        // 该书籍的已选择单词总数
        // user_voc_rev 中有该用户已选择的单词
        Integer allCount = vocMapper.getSelectedCountInBook(userId, bookId);
        // 该书籍的未选择单词总数
        UserBookStatisticsDTO userBookStatisticsDTO = new UserBookStatisticsDTO();
        userBookStatisticsDTO.setSelected(selectedCount);
        userBookStatisticsDTO.setTotal(allCount);
        userBookStatisticsDTO.setUnSelected(allCount - selectedCount);

        return userBookStatisticsDTO;
    }


    /**
     * 校验导入的excel文件是否合法
     *
     * @param file
     * @throws IOException
     */
    @Override
    public void vocExcelValidate(MultipartFile file) throws IOException {


        ReadListener<VocExcelDTO> readListener = new AnalysisEventListener<>() {
            int rowNum = 1;

            @Override
            public void invoke(VocExcelDTO vocExcelDTO, AnalysisContext analysisContext) {
                // 校验单元格中是否有空数据(是否有对象的属性值为null)
                String content = vocExcelDTO.getContent();

                if (content == null)
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 1, null, "单词不能为空");

                String ukPhonetic = vocExcelDTO.getUkPhonetic();
                if (ukPhonetic == null)
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 2, content, "英式音标不能为空");

                String usPhonetic = vocExcelDTO.getUsPhonetic();
                if (usPhonetic == null)
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 3, content, "美式音标不能为空");

                String ukPronounciation = vocExcelDTO.getUkPronounciation();

                if (ukPronounciation == null)
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 4, content, "英式发音文件名不能为空");
                String usPronounciation = vocExcelDTO.getUsPronounciation();
                if (usPronounciation == null)
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 5, content, "美式发音文件名不能为空");

                String interpretations = vocExcelDTO.getInterpretations();
                if (interpretations == null)
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 6, content, "释义不能为空");

                String exampleSentences = vocExcelDTO.getExampleSentences();
                if (exampleSentences == null)
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 7, content, "例句不能为空");

                String bookInfos = vocExcelDTO.getBookInfos();
                if (bookInfos == null)
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 8, content, "单词位置不能为空");


//                校验单词格式是否为 词性.词义

                String[] vocmeanings = interpretations.split("\n");
                for (String vocmeaning : vocmeanings) {
                    if (!vocmeaning.contains(".")) {
                        throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 6, content, "释义格式错误");
                    }
                }


                //        - 校验例句格式是否为: 英文例句\n例句中文释义
                String[] exampleSentence = exampleSentences.split("\n");
                if (exampleSentence.length < 2)
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 7, content, "例句格式错误");

                // 正则表达式匹配英文中文语句
                for (int i = 0; i < exampleSentence.length; i++) {
                    if (i % 2 == 0) {
                        // 英文例句
                        if (!exampleSentence[i].matches(CommonConstant.EXCEL_VOC_REGEX))
                            throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 7, content, "例句格式错误");
                    } else {
                        // 中文例句
                        if (!exampleSentence[i].matches(CommonConstant.EXCEL_CHINESE_REGEX))
                            throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 7, content, "例句格式错误");
                    }

                }


                //        - 校验单词所属的书籍或者章节是否存在
                String[] split = bookInfos.split("#");
                if (split.length != 2)
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 8, content, "单词书籍章节格式错误");

                String bookName = split[0];

                String chapterName = split[1].trim();

                new LambdaQueryWrapper<VocBookDO>()
                        .eq(VocBookDO::getName, bookName);

                VocBookDO vocBookDO = vocBookMapper.selectOne(new LambdaQueryWrapper<VocBookDO>()
                        .eq(VocBookDO::getName, bookName));

                if (vocBookDO == null)
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 8, content, "单词所属的书籍不存在");


                List<VocChapterDO> vocChapterDOS = vocChapterMapper.selectList(new LambdaQueryWrapper<VocChapterDO>().eq(VocChapterDO::getBookId, vocBookDO.getId()));
                List<VocChapterDO> collect = vocChapterDOS.stream().filter(vocChapterDO -> vocChapterDO.getChapterName().equals(chapterName))
                        .toList();
                if (collect.isEmpty())
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, this.rowNum, 8, content, "单词所属的章节不存在");

                // 每检查完一行  行数加1  从第一行开始
                this.rowNum++;

            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {

            }

            @Override
            public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
                if (headMap.size() != 8) {
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, "Excel文件头数量与模版文件头数量不一致");
                }

                boolean isHeaderValid =
                        headMap.get(0).trim().equals("单词") &&
                                headMap.get(1).trim().equals("英式音标") &&
                                headMap.get(2).trim().equals("美式音标") &&
                                headMap.get(3).trim().equals("英式发音文件名") &&
                                headMap.get(4).trim().equals("美式发音文件名") &&
                                headMap.get(5).trim().equals("释义") &&
                                headMap.get(6).trim().equals("例句") &&
                                headMap.get(7).trim().equals("单词位置");

                if (!isHeaderValid) {
                    throw new ExcelParseException(ResultCodeEnum.EXCEL_SAVE_ERROR, "Excel文件头内容与模版文件头内容不一致");
                }
            }
        };


        EasyExcel.read(file.getInputStream(), VocExcelDTO.class, readListener).sheet().doRead();


        System.out.println("数据解析");

    }

    /**
     * 通过excel批量添加单词信息
     *
     * @param file
     * @param userId
     * @return
     * @throws IOException
     */
    @Override
    @Transactional
    public ExcelAddOperateDTO addVocExcel(MultipartFile file, Long userId) throws IOException {

        ExcelAddOperateDTO excelAddOperateDTO = new ExcelAddOperateDTO();

        ReadListener<VocExcelDTO> readListener = new ReadListener<>() {

            int count = 0;

            @Override
            public void invoke(VocExcelDTO vocExcelDTO, AnalysisContext analysisContext) {

                // voc表 转换成DO对象插入数据库

                VocDO vocDO = vocConverter.vocExcelDTO2VocDO(vocExcelDTO);


                // 先查询数据库中是否有该数据
                VocDO vocDO1 = vocMapper.selectOne(new QueryWrapper<>(vocDO).eq("content", vocDO.getContent()));

                if (vocDO1 != null) {
                    throw new ExcelParseException(ResultCodeEnum.VOC_EXISTED, vocDO.getContent());
                } else {
                    // 将单词信息插入数据库
                    vocMapper.insert(vocDO);
                }

                // 对应单词释义 voc_meaning表
                String interpretations = vocExcelDTO.getInterpretations();
                //  传入表示voc_meaning字符串，解析对象并存入数据库
                getVocMeanDOFromString(interpretations, vocDO.getId());


                // 对应example_sentence表
                String exampleSentences = vocExcelDTO.getExampleSentences();
                getExampleSentenceDOFromString(exampleSentences, vocDO.getId());

                // 对应书籍和章节  voc_chap_book表  voc_chapter表
                String bookInfos = vocExcelDTO.getBookInfos();
                getVocChapBookDOFromString(bookInfos, vocDO.getId(), vocDO.getContent());

                count++;
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                excelAddOperateDTO.setTotalCount(count);
                System.out.println("读取完成");
            }
        };

        EasyExcel.read(file.getInputStream(), VocExcelDTO.class, readListener)
                .sheet().doRead();


        excelAddOperateDTO.setFileName(file.getOriginalFilename());


        return excelAddOperateDTO;
    }

    // 解析章节关系
    private void getVocChapBookDOFromString(String bookInfos, Long id, String content) {
        String[] split = bookInfos.split("#");
        // 检查章节、书籍是否存在
        LambdaQueryWrapper<VocChapterDO> vocChapBookDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
        vocChapBookDOLambdaQueryWrapper.eq(VocChapterDO::getBookName, split[0])
                .eq(VocChapterDO::getChapterName, split[1]);

        VocChapterDO vocChapterDO = vocChapterMapper.selectOne(vocChapBookDOLambdaQueryWrapper);

        if (vocChapterDO == null) {
            // 章节不存在
            // 返回错误信息
            throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_PARSE_ERROR, "章节或书籍信息不存在");
        } else {
            // 章节信息存在  将信息插入数据库
            // 插入voc_chap_book表

            VocChapBookDO vocChapBookDO = new VocChapBookDO();
            vocChapBookDO.setBookId(vocChapterDO.getBookId());
            vocChapBookDO.setBookName(vocChapterDO.getBookName());
            vocChapBookDO.setChapterId(vocChapterDO.getId());
            vocChapBookDO.setChapterName(vocChapterDO.getChapterName());
            // voc插入以后获取的id
            vocChapBookDO.setVocId(id);

            vocChapBookDO.setVocName(content);

            vocChapBookMapper.insert(vocChapBookDO);


            // 修改voc_chapter的voc_count字段 +1
            vocChapterMapper.update(
                    new UpdateWrapper<VocChapterDO>().eq("id", vocChapterDO.getId())
                            .set("voc_count", vocChapterDO.getVocCount() + 1)
            );


        }

    }
    // 解析例句字符转，生成example_sentenceDO对象集合并插入

    private void getExampleSentenceDOFromString(String exampleSentences, Long id) {
        String[] lines = exampleSentences.split("\\r?\\n|\\r");
        List<ExampleSentenceDO> exampleSentenceDOS = new ArrayList<>();


        // 获取例句和对应翻译
        for (int i = 0; i < lines.length; ) {
            ExampleSentenceDO exampleSentenceDO = new ExampleSentenceDO();
            exampleSentenceDO.setVocId(id);
            exampleSentenceDO.setContent(lines[i]);
            exampleSentenceDO.setMeaning(lines[i + 1]);

            exampleSentenceDOS.add(exampleSentenceDO);
            i += 2;
        }

        // 存入数据库

        exampleSentenceMapper.insert(exampleSentenceDOS);
    }

    private void getVocMeanDOFromString(String interpretations, Long vocId) {
        String[] lines = interpretations.split("\n");

        List<VocMeaningDO> vocMeaningDOS = new ArrayList<>();
        for (String line : lines) {
            String[] split = line.split("\\.");
            VocMeaningDO vocMeaningDO = new VocMeaningDO();
            // 存入单词id
            vocMeaningDO.setVocId(vocId);
            //存入单词类型type
            vocMeaningDO.setType(split[0] + ".");
            //存入单词内容Content
            vocMeaningDO.setInterContent(split[1]);
            vocMeaningDOS.add(vocMeaningDO);
        }
        vocMeaningMapper.insert(vocMeaningDOS);
    }

    /**
     * 删除单词语音文件  包括oss中的文件
     *
     * @param id
     * @param type
     * @param name
     * @return
     */
    @Override
    @Transactional
    public DeleteVocFileOperateDTO deleteFile(Long id, String type, String name) {


        VocDO vocDO = vocMapper.selectById(id);

        LambdaUpdateWrapper<VocDO> vocDOLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        vocDOLambdaUpdateWrapper.eq(VocDO::getId, id);

        if ("uk".equals(type)) {

            vocDOLambdaUpdateWrapper.setSql("uk_pronounciation = null");

        }
        if ("us".equals(type)) {

            vocDOLambdaUpdateWrapper.setSql("us_pronounciation = null");

        }


        // 删除oos文件
        fileService.deleteFile(name);

        DeleteVocFileOperateDTO deleteVocFileOperateDTO = new DeleteVocFileOperateDTO();
        deleteVocFileOperateDTO.setVocId(vocDO.getId());
        deleteVocFileOperateDTO.setContent(vocDO.getContent());
        deleteVocFileOperateDTO.setType(type);
        deleteVocFileOperateDTO.setFileName(name);

        return deleteVocFileOperateDTO;
    }

    /**
     * 删除voc_chap_book表中的数据
     * 删除章节表中的数据
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public DeleteVocRelationOperateDTO deleteVocRelation(Long id) {
        // 获取对象拿到vocChapterId
        VocChapBookDO vocChapBookDO = vocChapBookMapper.selectById(id);
        // 删除voc_chap_book表中的数据
        vocChapBookMapper.deleteById(id);

        UpdateWrapper<VocChapterDO> VocChapterWrapper = new UpdateWrapper<VocChapterDO>().eq("id", vocChapBookDO.getChapterId()).setSql("voc_count = voc_count - 1");

        // 根据id 修改 voc——chapter voc_count 的 值
        vocChapterMapper.update(VocChapterWrapper);
        // aop日志记录
        return vocConverter.toDeleteVocRelationOperateDTO(vocChapBookDO);

    }

    // 删除voc_meaning表数据
    @Override
    public DeleteInterpretationOperateDTO deleteInterpretation(Long id) {

        VocMeaningDO vocMeaningDO = vocMeaningMapper.selectById(id);
        if (vocMeaningDO != null) {
            vocMeaningMapper.deleteById(id);
        }

        if (vocMeaningDO != null) {
            return vocConverter.toDeleteInterpretationOperateDTO(vocMeaningDO, vocMeaningDO.getInterContent());
        }
        return null;
    }

    // 删除例句
    @Override
    public DeleteVocExampleOperateDTO deleteExample(Long id) {
        ExampleSentenceDO exampleSentenceDO = exampleSentenceMapper.selectById(id);
        if (exampleSentenceDO != null) {
            exampleSentenceMapper.deleteById(id);
        }

        if (exampleSentenceDO != null) {
            return vocConverter.toDeleteExampleOperateDTO(exampleSentenceDO, exampleSentenceDO.getContent());
        }
        return null;
    }

    // 单词语音上传
    @Override
    public String uploadsFile(MultipartFile file) throws IOException {
        String contentType = file.getContentType();

        return fileService.uploadFile(file, contentType);
    }

}
